/******************************************************************************
COPYRIGHT 2012   : ATECH
Project          : 
Source File Name : driverSPI.c
Group            : SoftWare Team
Author           : 
Date First Issued: 10/17/2012
********************************Documentation**********************************
Purpose -  This file is 
********************************RevisionHistory********************************
_______________________________________________________________________________
Date : MM/DD/YY    Release        Changes Description                  Author
Date : 10/26/2012    1.0                                                 
   
******************************************************************************/

#define driverSPI_c


/* #include */
#include "sys_micro.h"
#include "system.h"
#include "driverSPI.h"



/* #define */

#define OVERRUN_ERR      		 (1)       /* Overrun error flag bit   */
#define CHAR_IN_RX       		 (8)       /* Char is in RX buffer     */
#define FULL_TX          		(16)       /* Full transmit buffer     */
#define RUNINT_FROM_TX   		(32)       /* Interrupt is in progress */
#define FULL_RX          		(64)       /* Full receive buffer      */


/* typedef */

/* static variables */

/* static constants */
																							
/* static function prototypes */


/*****************************************************************************/
/**
 * Function Name: void ini_SPI(void)
 * Description:   
 *
 * Param:   none
 * Return:  none
 * Author:  
 *****************************************************************************/
void ini_SPI(void)
{
    /* SPI1 */
    SPI1CR1 = 0x04;     /* SPI module disabled */                    
    SPI1CR2 = 0x00;
    
    (void)SPI1SR;       /* Read the status register and */
    (void)SPI1DR;       /* read the data register to clear the status flags */
                                                                             
    /* Desired SPI baud rate = 500kHz, baud rate divider = (16MHz/0.5MHz) = 32 */    
    SPI1BR_SPPR = 0x03; /* Baud rate divider = (SPPR+1)*2^(SPR+1) = (4)*(2^3)=32 */
    SPI1BR_SPR  = 0x02;    
    
    SPI1CR2_MODFEN = 0; 
    SPI1CR2_SPISWAI= 1;
	SPI1CR2_XFRW   = 1;
	
    SPI1CR1_SSOE  = 0;   
  	SPI1CR1_LSBFE = 0;	 /*MSB first */

    SPI1CR1_MSTR  = 1;   /* SPI in Master mode */
    SPI1CR1_CPHA  = 1;   /* Data sampling at falling edges */
  	SPI1CR1_CPOL  = 0;   /* Data sampling at falling edges */
    SPI1CR1_SPE   = 1;   /* SPI module enabled */
    
    /* SPI1 */
    
    /* SPI2 */      

}

/*****************************************************************************/
/**
 * Function Name: void DisableSPI(void)
 * Description:   disable all spi module
 *
 * Param:   none
 * Return:  none
 * Author:  
 *****************************************************************************/
void DisableSPI(void) 
{
    /* spi0 */
    SPI1CR1 = 0x04;   /* SPI module disabled */                    
    SPI1CR2 = 0x00;

    /* spi1 */
    SPI1CR1 = 0x04;   /* SPI module disabled */                    
    SPI1CR2 = 0x00;
    
    /* spi2 */
    //SPI2CR1 = 0x04;   /* SPI module disabled */                    
    //SPI2CR2 = 0x00;  
  
}

/*****************************************************************************/
/**
 * Function Name: void Sleep_SPI(void)
 * Description:   Set SPI into Sleep
 *
 * Param:   none
 * Return:  none
 * Author:  
 *****************************************************************************/
void Sleep_SPI(void)
{
	  SPI1CR1_SPE = 0; 
}

/*****************************************************************************/
/**
 * Function Name: void Wake_SPI(void)
 * Description:   Wake up SPI form Sleep
 *
 * Param:   none
 * Return:  none
 * Author:  
 *****************************************************************************/
void Wake_SPI(void)
{
    SPI1CR1_SPE = 1; 
}	

/*****************************************************************************/
/**
 * Function Name: byte SPI_RecvChar(UINT16 *Chr)
 * Description:   SPI Recv Porcess
 *
 * Param:   none
 * Return:  none
 * Author:  
 *****************************************************************************/
byte SPI_RecvChar(UINT16 *Chr)
{
    if (!(SPI1SR & SPI1SR_SPIF_MASK)) 
	  {   /* Is receive buffer empty? */
		    return ERR_RXEMPTY ;              /* If yes then error is returned */
	  }
	
	  *Chr = SPI1DR;                       /* Read data from receiver */
  	return ERR_OK;
}

byte SPI_RecvCharBy8Bit(UINT8 *Chr)
{
    if (!(SPI1SR & SPI1SR_SPIF_MASK)) 
	  {   /* Is receive buffer empty? */
		    return ERR_RXEMPTY ;              /* If yes then error is returned */
	  }
	
	  *Chr = SPI1DRL;                       /* Read data from receiver */
  	return ERR_OK;
}

/*****************************************************************************/
/**
 * Function Name: byte SPI_SendChar(UINT16 Chr)
 * Description:    SPI Send Porcess
 *
 * Param:   none
 * Return:  none
 * Author:  
 *****************************************************************************/
byte SPI_SendChar(UINT16 Chr)
{
    if(!SPI1SR_SPTEF)
	  { 
		    return ERR_TXFULL;                
  	}
	
	  SPI1DR = Chr; 
	  return ERR_OK;                
}

byte SPI_SendCharBy8Bit(UINT8 Chr)
{
    if(!SPI1SR_SPTEF)
	  { 
		    return ERR_TXFULL;                
  	}
	
	  SPI1DRL = Chr; 
	  return ERR_OK;                
}

/****************************************************************************/
/**
 * Function Name: SPI_DataCom
 * Description: none
 *
 * Param:   none
 * Return:  none
 * Author:  2015/06/08, hui.pang create this function
 ****************************************************************************/
UINT8 SPI_DataComBy8Bit( UINT8 u8_send_data, UINT8 *p_u8_rec_data )
{
    UINT16 u16_delay = 10000;
    UINT8 u8_err = 0;

    NOP();
    NOP();

    u8_err = SPI_SendCharBy8Bit(u8_send_data);
    if( ERR_OK != u8_err )
    {
        return u8_err;
    }

    while((ERR_OK != SPI_RecvCharBy8Bit(p_u8_rec_data)) && (--u16_delay != 0));

    if( 0 == u16_delay )
    {
        return ERR_RXEMPTY; 
    }

    NOP();
    NOP();

    ini_SPI();

    NOP();
    NOP();

    return ERR_OK;
}

UINT8 SPI_DataCom( UINT16 u16_send_data, UINT16 *p_u16_rec_data )
{
    UINT16 u16_delay = 10000;
    UINT8 u8_err = 0;

    NOP();
    NOP();

    u8_err = SPI_SendChar(u16_send_data);
    if( ERR_OK != u8_err )
    {
        return u8_err;
    }

    while((ERR_OK != SPI_RecvChar(p_u16_rec_data)) && (--u16_delay != 0));

    if( 0 == u16_delay )
    {
        return ERR_RXEMPTY; 
    }

    NOP();
    NOP();

    return ERR_OK;
}

/*************************end of driverSPI.c**********************************/

/******************************************************************************
 Revision Notes:

For each change to this file, be sure to record:
1. Who made the change and when the change was made.
2. Why the change was made and the intended result.

  Date     By     Reason For Change
mm/dd/yy  XXX     -----------------

******************************************************************************/